package org.demo.ws;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.params.HttpParams;
import org.apache.http.util.EntityUtils;

/**
 * 使用 commons-httpclient 调用 Web Service
 * @author  
 * @date    2011-1-6
 * @file    org.demo.ws.HttpClientProxy.java
 */
public class HttpClientProxy{

	private static final String WS_METHOD= "${methodName}";
	
	/**
	 * 测试
	 * @param args
	 * @throws IOException
	 */
	public static void main(String[] args) throws IOException {
		HttpClientProxy proxy = new HttpClientProxy();
		String path = HttpClientProxy.class.getResource("HttpClientSoap.xml").getFile();
		String location = "http://localhost:8080/axis2/services/HelloServiceTest.HelloServiceTestHttpSoap11Endpoint/";
		String methodName = "detail";
		Object[] objs = new Object[]{12, 1234, 12.01, 12.02, "hello"};
		String result = proxy.invoke(path, location, methodName, objs);
		System.out.println(result);
	}
	/**
	 * 调用 Web Service 方法
	 * @param soapFilePath
	 * @param location
	 * @param methodName
	 * @param args
	 * @return
	 * @throws IOException
	 */
	public String invoke(String soapFilePath, String location,
			String methodName, Object[] args) throws IOException {
		
		// 1. 预处理 soap 文件，替换掉 ${methodName},${0},${1}...
		StringBuilder sb = getFileContent(soapFilePath);
		// 替换 method 开始标签
		replace(sb, WS_METHOD, methodName);
		// 替换 method 结束标签
		replace(sb, WS_METHOD, methodName);
		// 替换方法参数
		if (args != null){
			for (int i=0; i<args.length; i++){
				replace(sb, "${" + i + "}", String.valueOf(args[i]));
			}
		}
		
		// 2. 创建 post
		HttpPost post = new HttpPost(location);
		post.setHeader("Content-Type", "text/xml");
		post.setEntity(new StringEntity(sb.toString()));
		
		// 3. 创建 httpClient
		HttpParams params = new BasicHttpParams();
		params.setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 6000);
		params.setParameter(CoreConnectionPNames.SO_TIMEOUT, 6000);
		// 多线程支持
		SchemeRegistry schemeReg = new SchemeRegistry();
		schemeReg.register(new Scheme("http", new PlainSocketFactory(), 8080));
		ThreadSafeClientConnManager connMgr = new ThreadSafeClientConnManager(params, schemeReg);
		
		HttpClient client = new DefaultHttpClient(connMgr, params);
		
		// 4. 执行 post 方法
		HttpResponse resp = client.execute(post);
		String result = EntityUtils.toString(resp.getEntity());
		
		// 5. 返回结果
		return result;
	}
	/**
	 * 获取文件内容
	 * @param filePath
	 * @return
	 * @throws IOException 
	 */
	private StringBuilder getFileContent(String filePath) throws IOException{
		StringBuilder sb = new StringBuilder();
		FileReader fr = null;
		try {
			fr = new FileReader(filePath);
			BufferedReader br = new BufferedReader(fr);
			String line = null;
			while((line = br.readLine()) != null){
				sb.append(line).append("\r\n");
			}
			br.close();
		} finally{
			try {if (fr != null){ fr.close(); }}catch(Exception e){}
		}
		return sb;
	}
	/**
	 * 替换 StringBuilder 中的字符串
	 * @param sb
	 * @param oldStr
	 * @param newStr
	 * @return
	 */
	private StringBuilder replace(StringBuilder sb, String oldStr, String newStr){
		int start = sb.indexOf(oldStr);
		if (start != -1){
			sb.replace(start, start + oldStr.length(), newStr);			
		}
		return sb;
	}
}
